<?php
/**
 * 后台基类控制器
 * ===============================================
 * @copyright 深圳市顶速网络科技有限公司  http://fasttop.top
 * ===============================================
 * @author 小陈先生 <945146147@qq.com>
 * @version 20150430
 */
namespace Common\Controller;
class AdminBaseController extends \Think\Controller {
	
	//保存禁止URL访问的公共方法，例如定义在控制器中的工具方法，deny优先级高于allow
	protected $deny = array ('getMenus' );
	
	/**
	 * 后台初始化方法
	 * @access public
	 */
	public function _initialize() {
		// 获取当前用户ID
		define ( 'UID', D ( 'User' )->checkLogin () );
		// 还没登录 跳转到登录页面
		if (! UID) {
			$this->redirect ( 'Public/login' );
		}
		/* 读取数据库中的配置 */
		$config = S ( 'DB_CONFIG_DATA' );
		if (! $config) {
			$config = D ( 'Config' )->getList ();
			S ( 'DB_CONFIG_DATA', $config );
		}
		C ( $config ); // 添加配置
		/* 是否是超级管理员	*/
		define ( 'IS_ROOT', D ( 'User' )->checkAdministrator () );
		if (! IS_ROOT && C ( 'ADMIN_ALLOW_IP' )) {
			// 检查IP地址访问
			if (! in_array ( get_client_ip (), explode ( ',', C ( 'ADMIN_ALLOW_IP' ) ) )) {
				$this->error ( '403:禁止访问' );
			}
		}
		$this->checkAuth (); //检测访问权限，超级管理员允许访问任何页面
		$this->assign ( '__MENU__', $this->getMenus () );
	}
	
	/**
	 * 权限检测，超管允许访问任何页面
	 */
	final protected function checkAuth() {
		$access = $this->accessControl ();
		if ($access === false) {
			$this->error ( '403:禁止访问' );
		} elseif ($access === null) {
			$dynamic = $this->checkDynamic (); //检测分类栏目有关的各项动态权限
			if ($dynamic === null) {
				//检测非动态权限
				$rule = strtolower ( MODULE_NAME . '/' . CONTROLLER_NAME . '/' . ACTION_NAME );
				if (! $this->checkRule ( $rule, array ('in', '1,2' ) )) {
					$this->error ( '未授权访问!' );
				}
			} elseif ($dynamic === false) {
				$this->error ( '未授权访问!' );
			}
		}
	}
	
	/**
	 * action访问控制，在“登录成功”后执行的第一项权限检测任务
	 * @return boolen|null 返回值必须使用“===”进行判断
	 * 返回“false”，不允许任何人访问（超管除外）
	 * 返回“null”，需要继续执行节点权限检测决定是否允许访问
	 * 返回“true”，允许任何管理员访问，无须节点检测权限
	 */
	final protected function accessControl() {
		if (IS_ROOT) {
			return true; //超管允许访问任何页面
		}
		$allow = C ( 'ALLOW_VISIT' ); //不受限控制器方法
		$deny = C ( 'DENY_VISIT' ); //超管专限控制器方法
		$check = strtolower ( CONTROLLER_NAME . '/' . ACTION_NAME );
		if (! empty ( $deny ) && in_array_case ( $check, $deny )) {
			return false; //非超管禁止访问deny中的方法
		}
		if (! empty ( $allow ) && in_array_case ( $check, $allow )) {
			return true;
		}
		return null; //需要继续下一步，检测节点权限
	}
	
	/**
	 * 检测是否是需要动态判断的权限
	 */
	protected function checkDynamic() {
		if (IS_ROOT) {
			return true; //超管允许访问任何页面
		}
		return null; //继续下一步，检测节点权限
	}
	
	/**
	 * 权限节点检测
	 * @param string $rule
	 * @param array|string $type
	 * @param string $mode 
	 */
	final protected function checkRule($rule, $type = '1', $mode = 'url') {
		if (IS_ROOT) {
			return true; //超管允许访问任何页面
		}
		$auth = new \Think\Auth ();
		if (! $auth->check ( $rule, UID, $type, $mode )) {
			return false;
		}
		return true;
	}
	
	/**
	 * 获取后台菜单
	 */
	public function getMenus() {
		$where ['module'] = MODULE_NAME;
		$where ['parentid'] = 0;
		$where ['status'] = 1;
		$where ['is_main'] = 1;
		$menus = D ( 'Menu' )->getList ( '*', $where, 'sort_order desc' ); //获取主菜单
		$temp = $this->getCurrentMenu (); //获取当前菜单信息
		$menulist = $this->checkMenuAuth ( $menus, 2, $temp [0] ['title'] ); //检测主菜单访问权限
		foreach ( $menulist as $k => $v ) { //构建二级菜单
			$map ['module'] = MODULE_NAME;
			$map ['parentid'] = $v ['id'];
			$map ['status'] = 1;
			$map ['is_main'] = 1;
			$childMenus = D ( 'Menu' )->getList ( '*', $map, 'sort_order desc' );
			if ($childMenus) {
				$childlist = $this->checkMenuAuth ( $childMenus, 1, $temp [1] ['title'] ); //检测子菜单访问权限
				$menulist [$k] ['child'] = $childlist;
			}
		}
		return $menulist;
	}
	
	/**
	 * 获取当前菜单信息
	 */
	final public function getCurrentMenu() {
		$temp = array ();
		$condition ['url'] = array ('like', '%' . CONTROLLER_NAME . '/' . ACTION_NAME . '%' );
		$current = D ( 'Menu' )->getMenuField ( 'id', $condition );
		if ($current) {
			$temp = D ( 'Menu' )->getPathById ( $current ['id'] );
		}
		return $temp;
	}
	
	/**
	 * 检测菜单（主菜单、子菜单）访问权限
	 * @param array $menu
	 * @param int $type
	 */
	final protected function checkMenuAuth($menu, $type, $temp = '') {
		foreach ( $menu as $key => $value ) {
			if ($value ['title'] == $temp) {
				$value ['current'] = "class='active'";
			}
			if (UID != C ( 'USER_ADMINISTRATOR' )) { //不属于超管访问时检测访问节点权限
				if (stripos ( $value ['url'], MODULE_NAME ) !== 0) {
					$value ['url'] = MODULE_NAME . '/' . $value ['url'];
				}
				if (! $this->checkRule ( $value ['url'], $type, null )) { //判断主菜单权限
					unset ( $menu [$key] );
					continue;
				}
			}
			$menulist [$key] = $value;
		}
		return $menulist;
	}
	
	/**
	 * 空操作
	 */
	public function _empty() {
		header ( 'Location:./404.html' );
	}
	
	/**
	 * 分页设置
	 * @param string $count
	 * @param string $listRows 
	 */
	public function paging($count, $listRows = 0) {
		$page = new \Org\Util\Pages ( $count, $listRows );
		//设置分页样式
		$page->setConfig ( 'theme', '%HEADER% %FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END%' );
		$pages = $page->show ();
		$this->assign ( 'page', $pages );
		return $page->firstRow . ',' . $page->listRows;
	}
	
	/**
	 * 通用添加  - 页面显示
	 */
	final public function add() {
		$this->display ( 'edit' );
	}
	
	/**
	 * 通用编辑 - 页面显示
	 */
	final public function edit() {
		$id = I ( 'get.id' );
		if (empty ( $id )) {
			$this->error ( L ( 'error_illegal_operation' ) );
		}
		$model = CONTROLLER_NAME;
		$detail = D ( $model )->getById ( $id );
		$this->assign ( $detail );
		$this->display ();
	}
	
	final protected function lists($model, $where = array(), $order = 'id asc') {
		if (is_string ( $model )) {
			$model = M ( $model );
		}
		$pk = $model->getPk ();
	}
	
	/**
	 * 通用新增
	 */
	final public function insert() {
		if (IS_POST && isset ( $_POST ['dosubmit'] )) {
			$postdata = I ( 'post.' );
			$model = CONTROLLER_NAME;
			if (false === D ( $model )->create ()) {
				$this->error ( D ( $model )->getError () );
			} else {
				if (D ( $model )->add ()) {
					$this->success ( L ( 'success_insert' ), U ( $model . '/index' ) );
				} else {
					$this->error ( L ( 'error_insert' ) );
				}
			}
		} else {
			$this->error ( L ( 'error_illegal_operation' ) );
		}
	}
	
	/**
	 * 通用更新
	 */
	final public function update() {
		if (IS_POST && isset ( $_POST ['dosubmit'] )) {
			$postdata = I ( 'post.' );
			$model = CONTROLLER_NAME;
			if (false === D ( $model )->create ()) {
				$this->error ( D ( $model )->getError () );
			} else {
				if (D ( $model )->save ()) {
					$this->success ( L ( 'success_edit' ), U ( $model . '/index' ) );
				} else {
					$this->error ( L ( 'error_edit' ) );
				}
			}
		} else {
			$this->error ( L ( 'error_illegal_operation' ) );
		}
	}
	
	/**
	 * 通用排序
	 */
	final public function listorder() {
		if (IS_POST && isset ( $_POST ['dosubmit'] )) {
			$sort_order = I ( 'post.sort_order' );
			$model = CONTROLLER_NAME;
			if ($sort_order) {
				foreach ( $sort_order as $k => $sort ) {
					$data ['id'] = $k;
					$data ['sort_order'] = $sort;
					D ( $model )->save ( $data );
				}
				$this->success ( L ( 'success_listorder' ) );
			}
		}
		$this->error ( L ( 'error_illegal_operation' ) );
	}
	
	/**
	 * 通用删除
	 */
	final public function delete() {
		$id = I ( 'get.id' );
		if (empty ( $id )) {
			echo json_encode ( array ('info' => L ( 'error_select_the_data' ) ) );
			exit ();
		}
		$model = CONTROLLER_NAME;
		if (false === D ( $model )->delete ( $id )) {
			$return = array ('info' => L ( 'error_delete' ) );
		} else {
			$return = array ('info' => L ( 'success_delete' ) );
		}
		echo json_encode ( $return );
		exit ();
	}
	
	/**
	 * 通用批量删除
	 */
	final public function delBatch() {
		if (IS_POST && isset ( $_POST ['dosubmit'] )) {
			$ids = I ( 'post.ids' );
			$model = CONTROLLER_NAME;
			if ($ids) {
				foreach ( $ids as $id ) {
					D ( $model )->delete ( $id );
				}
				$this->success ( L ( 'success_delete' ) );
			}
		}
		$this->error ( L ( 'error_illegal_operation' ) );
	}
	
	/**
	 * 通用更改状态
	 */
	final public function status() {
		$getdata = I ( 'get.' );
		if (empty ( $getdata ['id'] )) {
			$this->error ( L ( 'error_illegal_operation' ) );
		}
		$getdata ['status'] = empty ( $getdata ['status'] ) ? 1 : 0;
		$model = CONTROLLER_NAME;
		$result = D ( $model )->save ( $getdata );
		if ($result) {
			$this->success ( L ( 'success_edit' ), U ( 'index' ) );
		} else {
			$this->error ( L ( 'error_edit' ) );
		}
	}
}